package com.pxmeta.party.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pxmeta.common.constant.Status;
import com.pxmeta.common.exception.ServiceException;
import com.pxmeta.party.entity.Association;
import com.pxmeta.party.entity.AssociationUser;
import com.pxmeta.party.mapper.AssociationUserMapper;
import com.pxmeta.party.service.IAssociationService;
import com.pxmeta.party.service.IAssociationUserService;
import com.pxmeta.user.entity.User;
import com.pxmeta.user.service.IUserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class AssociationUserServiceImpl extends ServiceImpl<AssociationUserMapper, AssociationUser> implements IAssociationUserService {

    @Autowired
    private IUserService userService;

    @Override
    public void signing(Long userId, Long associationId, Integer signingTime, BigDecimal finalRate) {

        AssociationUser currentAssociationUser = getUserSign(userId);
        if (null != currentAssociationUser){
            throw new ServiceException("您已经有公会了，不能再次签约。");
        }

        LambdaQueryWrapper<AssociationUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(AssociationUser::getUserId, userId)
                .eq(AssociationUser::getAssociationId, associationId)
                .ne(AssociationUser::getStatus, Status.FAIL.getValue());
        AssociationUser exist = this.getOne(wrapper);
        if (exist != null){
            throw new ServiceException("您已申请过一次，请勿重复申请");
        }
        AssociationUser associationUser = new AssociationUser();
        associationUser.setUserId(userId);
        associationUser.setStatus(Status.PENDING.getValue());
        associationUser.setSigningTime(signingTime);
        associationUser.setAssociationId(associationId);
        associationUser.setCommissionRatio(finalRate);
        this.save(associationUser);
    }

    @Override
    public IPage<AssociationUser> getSigningList(Long associationId, Integer status, Integer page, Integer size) {
        LambdaQueryWrapper<AssociationUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(AssociationUser::getAssociationId, associationId);
        if (status != null){
            wrapper.eq(AssociationUser::getStatus, status);
        }
        wrapper.orderByDesc(AssociationUser::getCreateTime);
        Page<AssociationUser> result = this.page(new Page<>(page, size), wrapper);
        List<AssociationUser> records = result.getRecords();
        if (CollectionUtil.isNotEmpty(records)){
            List<Long> userIds = records.stream().map(AssociationUser::getUserId).collect(Collectors.toList());

            List<User> users = userService.listByIds(userIds);

            records.forEach(r-> users.forEach(u->{
                if (u.getId().equals(r.getUserId())){
                    r.setUser(u);
                }
            }));
        }
        return result;
    }

    @Override
    public List<AssociationUser> getUserList(Long associationId) {
        LambdaQueryWrapper<AssociationUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(AssociationUser::getAssociationId, associationId);
        return this.list(wrapper);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void approval(Long associationId, Long userId, Integer status) {
        LambdaQueryWrapper<AssociationUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(AssociationUser::getAssociationId, associationId)
                .eq(AssociationUser::getUserId, userId);


        User user = userService.getById(userId);

        User updateUser = new User();
        updateUser.setId(user.getId());
        if (Status.SUCCESS.getValue().equals(status)){
            //查询用户是否已经加入公会
            AssociationUser userSign = this.getUserSign(userId);
            if (null != userSign){
                throw new ServiceException("用户已签约其他公会！");
            }
            //如果同意，则更新用户家族状态。
            updateUser.setAssociationId(associationId);
            userService.updateById(updateUser);
        }

        if (Status.FAIL.getValue().equals(status) &&
                associationId.equals(user.getAssociationId())){
            updateUser.setAssociationId(null);
            userService.updateById(updateUser);
        }

        AssociationUser associationUser = this.getOne(wrapper);
        associationUser.setStatus(status);
        this.updateById(associationUser);
    }

    @Override
    public AssociationUser getUserSign(Long userId) {
        LambdaQueryWrapper<AssociationUser> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(AssociationUser::getUserId, userId)
                .eq(AssociationUser::getStatus, Status.SUCCESS.getValue());

        return this.getOne(wrapper);
    }

}
